﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace ChineseChess.Game.AI
{
    public class Ai2: BaseAi
    {
        /// <summary>
        /// Ai的算法
        /// </summary>
        /// <param name="pieceList">当前局面</param>
        /// <param name="canvas"></param>
        /// <param name="deep">计算深度</param>
        public static void Run(List<Piece> pieceList, Canvas canvas, int deep = 3)
        {
            List<Piece> pies = CopyList(pieceList);
            Moves mv = search(pies, deep);

            Piece p = clearPiece(pieceList, (int)mv.p.X, (int)mv.p.Y);//吃掉子
            MessageBox.Show(mv.pie.Name.ToString() + mv.pie.X + "," + mv.pie.Y + ", " + mv.p.ToString());
            if (p != null)
            {
                canvas.Children.Remove(p);
            }

            for (int i = 0; i < pieceList.Count; i++)
            {
                var pie = pieceList[i];
                if (pie.X == mv.pie.X && pie.Y == mv.pie.Y)
                {
                    pie.X = (int)mv.p.X;
                    pie.Y = (int)mv.p.Y;
                    pie.InvalidateVisual();
                }
            }
        }

        public static Moves search(List<Piece> pieceList,int deep)
        {
            Moves bestMv = null;
            int best = int.MinValue;
            List<Moves> mvs = generateMoves(pieceList, false); //获得黑子所有可能的走子

            for (int i = 0; i < mvs.Count; i++)
            {
                Moves mv = mvs[i];
                Moves historyMv;
                Piece eatedPie = MovePie(pieceList, mv, out historyMv);
                int value = alphaBeta(pieceList,deep, int.MinValue, int.MaxValue, false);
                if (bestMv == null || value > best)
                {
                    best = value;
                    bestMv = mv;
                }

                BackMovePie(pieceList, eatedPie, historyMv);

            }

            return bestMv;
        }

        private static int alphaBeta(List<Piece> pieceList,int depth, int alpha, int beta, bool isMax)
        {
            if(depth == 0)
            {
                return getScore(pieceList, false);
            }
            List<Moves> mvs = generateMoves(pieceList, isMax);

            for (int i = 0; i < mvs.Count; i++)
            {
                Moves mv = mvs[i];
                int finalBeta = beta;
                int finalAlpha = alpha;
                int finalDepth = depth;
                int temp = 0;
                Moves historyMv;
                Piece eatedPie = MovePie(pieceList, mv,out historyMv);
                if (isMax)
                {
                    alpha = Math.Max(alpha, alphaBeta(pieceList, depth - 1, alpha, beta, false));
                }
                else
                {
                    beta = Math.Min(beta, alphaBeta(pieceList,depth - 1, alpha, beta, true));
                }

                BackMovePie(pieceList, eatedPie , historyMv);

                if (beta<=alpha)
                {
                    break;
                }
            }

            return isMax ? alpha : beta;
        }


    }
}
